package com.s7.widget.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ScrollView;

import androidx.annotation.RequiresApi;

import com.s7.widget.R;
import com.s7.widget.listener.OnTranslucentListener;


/**
 * Created by Administor on 2018\3\20 0020.
 * 标题栏渐变/菜单顶部固定 ScrollView
 */
public class GradualTabScrollView extends ScrollView {

    /**
     * 第一个View的高度 + 状态栏高度 （如果开启渐变 + 标题栏高度）
     */
    private int mHeaderHeight = 0;

    /**
     * 主体高度
     */
    private int mFooterHeight = 0;

    /**
     * 主体（headerView + tabView + footerView 的父布局）
     */
    private ViewGroup chidView;

    /**
     * 第一个View高度（渐变范围/要隐藏的View）
     */
    private View headerView;

    /**
     * 第二个View高度（可固定菜单View）
     */
    private View tabView;

    /**
     * 第三个View高度（内容）
     */
    private View footerView;

    /**
     * 标题栏（用以渐变标题栏使用）
     */
    private View titleBar;

    /**
     * 是不是沉浸式布局
     */
    private boolean isSteep = false;

    /**
     * 固定菜单栏时，是否加上标题栏高度
     */
    private boolean isTitleHeight = false;

    /**
     * 状态栏高度
     */
    private float stateBarHeight = 0;

    /**
     * 是否开启渐变
     */
    private boolean isShade = false;

    /**
     * 是否开启顶部固定菜单栏
     */
    private boolean isFixedTab = false;

    /**
     * 是否下发事件给内部控件
     */
    private boolean isIntercept = false;

    /**
     * 渐变回调
     */
    private OnTranslucentListener mListener;


    public GradualTabScrollView(Context context) {
        super(context);
    }

    public GradualTabScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GradualTabScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr, 0);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public GradualTabScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs, defStyleAttr, defStyleRes);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GradualTabScrollView, defStyleAttr, defStyleRes);
        setShade(a.getBoolean(R.styleable.GradualTabScrollView_isShade, false));
        setFixedTab(a.getBoolean(R.styleable.GradualTabScrollView_isFixedTab, false));
        setShade(a.getBoolean(R.styleable.GradualTabScrollView_isSteep, false));
        setFixedTab(a.getBoolean(R.styleable.GradualTabScrollView_isTitleHeight, false));
        a.recycle();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        chidView = (ViewGroup) getChildAt(0);
        if (chidView == null) {
            return;
        }

        /**
         * 是否开启渐变
         */
        if (isShade() && chidView.getChildCount() > 0 ) {
            headerView = chidView.getChildAt(0);
            /**
             * 判断是否是沉浸式
             */
            if (isSteep) {
                mHeaderHeight = (int) (headerView.getHeight() - stateBarHeight);
            } else {
                mHeaderHeight = headerView.getHeight();
            }
        }

        /**
         * 是否固定菜单
         */
        if (isFixedTab() && chidView.getChildCount() == 3) {
            headerView = chidView.getChildAt(0);
            tabView = chidView.getChildAt(1);
            footerView = chidView.getChildAt(2);

            /**
             * 判断是否是沉浸式
             */
            if (isSteep) {
                mHeaderHeight = (int) (headerView.getHeight() - stateBarHeight);
            } else {
                mHeaderHeight = headerView.getHeight();
            }

            /**
             * footerView高度＋tobView高度＋headerView高度 = scrollview高度(getHeight)
             * 这样scrollview最多刚好滚动到除了导航条，其余的都是footerView
             */

            if (isTitleHeight) {
                mFooterHeight = (int) (getHeight() - tabView.getMeasuredHeight() - stateBarHeight + titleBar.getMeasuredHeight());
            } else {
                mFooterHeight = (int) (getHeight() - tabView.getMeasuredHeight() - stateBarHeight);
            }

            footerView.setLayoutParams(new LinearLayout.LayoutParams(getWidth(), mFooterHeight));
        }

        /**
         * 防止进入时显示的不是最顶部
         */
        if (headerView != null) {
            headerView.setFocusable(true);
            headerView.setFocusableInTouchMode(true);
            headerView.requestFocus();
        }
    }

    /**
     * @param l Current horizontal scroll origin. 当前滑动的x轴距离
     * @param t Current vertical scroll origin. 当前滑动的y轴距离
     * @param oldl Previous horizontal scroll origin. 上一次滑动的x轴距离
     * @param oldt Previous vertical scroll origin. 上一次滑动的y轴距离
     */
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        initGradualScroll(l, t, oldl, oldt);
        initFixedTab(l, t, oldl, oldt);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return isIntercept ? false : super.onInterceptTouchEvent(ev);
    }

    /**
     * 固定菜单栏
     * @param l
     * @param t
     * @param oldl
     * @param oldt
     */
    private void initFixedTab(int l, int t, int oldl, int oldt) {
        if (isFixedTab()) {
            /**
             * 判断顶部布局是否滑出屏幕外
             */
            if (t >= mHeaderHeight) {
                isIntercept = true;
            } else {
                isIntercept = false;
            }
        }
    }

    /**
     * 是否读取标题栏高度
     */
    private boolean flag = true;

    /**
     * 开启渐变时，滚动处理
     * @param l
     * @param t
     * @param oldl
     * @param oldt
     */
    private void initGradualScroll(int l, int t, int oldl, int oldt) {

        /**
         * 是否读去标题栏高度
         */
        if (titleBar != null) {
            /**
             * 避免标题栏未绘制，在此次读取标题栏高度
             */
            if (flag) {
                flag = false;
                mHeaderHeight = mHeaderHeight - titleBar.getHeight();
            }
        }

        /**
         * 是否开启渐变
         */
        if (isShade()) {
            if (t <= 0) {
                if (mListener != null) {
                    mListener.onTranslucent(0);
                }
            } else if (t > 0 && t < mHeaderHeight) {
                float scale = (float) t / mHeaderHeight;
                float alpha = (255 * scale);
                if (mListener != null) {
                    mListener.onTranslucent(alpha);
                }
            } else {
                if (mListener != null) {
                    mListener.onTranslucent(255);
                }
            }
        }
    }

    /**
     * 获取渐变状态
     * @return
     */
    public boolean isShade() {
        return isShade;
    }

    /**
     * 设置是否开启渐变
     * @param shade
     */
    public void setShade(boolean shade) {
        this.isShade = shade;
    }

    /**
     * 获取固定菜单状态
     * @return
     */
    public boolean isFixedTab() {
        return isFixedTab;
    }

    /**
     * 设置是否开启顶部固定菜单
     * @param fixedTab
     */
    public void setFixedTab(boolean fixedTab) {
        isFixedTab = fixedTab;
    }

    /**
     * 设置是否是沉浸式布局
     * @param steep
     */
    public void setSteep(boolean steep) {
        isSteep = steep;
    }

    /**
     * 是否加上标题栏高度
     * @param titleHeight
     */
    public void setTitleHeight(boolean titleHeight) {
        isTitleHeight = titleHeight;
    }

    /**
     * 获取标题栏
     * @return
     */
    public View getTitleBar() {
        return titleBar;
    }

    /**
     * 设置标题栏
     * @param titleBar
     */
    public void setTitleBar(View titleBar) {
        this.titleBar = titleBar;
    }

    /**
     * 获取状态栏高度
     * @return
     */
    public float getStateBarHeight() {
        return stateBarHeight;
    }

    /**
     * 设置状态栏高度
     * @param stateBarHeight
     */
    public void setStateBarHeight(float stateBarHeight) {
        this.stateBarHeight = stateBarHeight;
    }

    /**
     * 设置渐变回调
     * @param mListener
     */
    public void setTranslucentListener(OnTranslucentListener mListener) {
        this.mListener = mListener;
    }

}
